package br.ufrj.ad.evento;

import org.apache.log4j.Logger;

import br.ufrj.ad.As;
import br.ufrj.ad.entidade.Peer;
import br.ufrj.ad.entidade.Rodada;
import br.ufrj.ad.entidade.Seed;
import br.ufrj.ad.estatistica.Amostragem;

public abstract class Upload extends Evento {
	private static final Logger log = Logger.getLogger(Upload.class);
			
	public Upload(double tempo, Peer peer, Rodada rodada, As as) {
		super(tempo, peer, rodada, as);
	}

	@Override
	void proximoEvento(Rodada rodadaProximoEvento) {
		Peer peerDestino = peer.escolheDestinoUpload();
		if(peerDestino != null) {
			int blocoId = peer.escolheBloco(peerDestino);
			boolean virouSeed = peerDestino.recebeBloco(blocoId);
			
			// se blocoId < 0 não teve upload e o peer não virou seed
			if(virouSeed) {
				//já recebeu todos os blocos
				log.debug(peer+" upou para "+peerDestino);
				Seed seed = new Seed(peerDestino);
				//o tempo que durou o download é agora - quando o cara chegou pq ele terminou o download aqui e está virando seed.
				rodada.addTempoDownload(tempo, tempo - seed.getTempoChegada());
				seed.setTempoSaida(tempo + Amostragem.exponencial(as.parametros.GAMA));
				as.eventos.add(new Saida(seed, rodadaProximoEvento, as));
				
				as.peers.remove(peerDestino);
				as.eventos.removeAll(peerDestino.getUploadsAgendados());
				
				//peerDestino deixou de ser um peer e virou seed pq recebeu o arquivo já
				as.seeds.add(seed);
				
				double tempoUpload = tempo + Amostragem.exponencial(as.parametros.MI);
				if(tempoUpload < seed.getTempoSaida()) {
					as.eventos.add(new SeedUpload(tempoUpload , seed, rodadaProximoEvento, as));
				}
			}
		}
		agendaProximoUpload(rodadaProximoEvento);
	}

	abstract void agendaProximoUpload(Rodada rodada);
}
